loading the package

library(ggplot2)
Need help getting started? Try the R Graphics Cookbook: https://r-graphics.org
library(gplots)

Attaching package: ‘gplots’

The following object is masked from ‘package:stats’:

    lowess
library(bnlearn)

Load the data

source('loadHNSCCdata.R')

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

Loading required package: nationalparkcolors
library(reshape)

Attaching package: ‘reshape’

The following objects are masked from ‘package:tidyr’:

    expand, smiths

The following object is masked from ‘package:dplyr’:

    rename
tumProtTable <- cast(tumProts, Gene~patient, mean)
Using inferredTumAbund as value column.  Use the value argument to cast to override this choice
rownames(tumProtTable) <- paste0(tumProtTable$Gene, "_T")
tumProtTable$Gene <- NULL
normProtTable <- cast(normProts, Gene~patient, mean)
Using inferredNormAbund as value column.  Use the value argument to cast to override this choice
rownames(normProtTable) <- paste0(normProtTable$Gene, "_N")
normProtTable$Gene <- NULL
imgFeatTable <- cast(imgFeat, Feature_Type~patient, mean)
rownames(imgFeatTable) <- imgFeatTable$Feature_Type
imgFeatTable$Feature_Type <- NULL

lnTableAll <- red.dat
lnTableAll$affected <- abs(unclass(factor(lnTableAll$lnSpread)) - 2)
lnTableAll$NoLN <- abs(unclass(factor(lnTableAll$lnCounts)) - 3)
lnTable <- as.data.frame(lnTableAll[ ,c("patient", "affected", "NoLN")])
lnAfTable <- as.data.frame(lnTableAll[ ,c("patient", "affected")])
lnNoTable <- as.data.frame(lnTableAll[ ,c("patient", "NoLN")])

rownames(lnTable) <- lnTable$patient
rownames(lnAfTable) <- lnTable$patient 
rownames(lnNoTable) <- lnTable$patient
lnTable$patient <- NULL 
lnAfTable$patient <- NULL 
lnNoTable$patient <- NULL
lnTableF <- as.data.frame(t(lnTable))
lnAfTableF <- as.data.frame(t(lnAfTable))
lnNoTableF <- as.data.frame(t(lnNoTable))
load("./analysis_SF/allCorrs.RData")
features <- c("Complexity", "InterquartileRange", "LeastAxisLength", "MajorAxisLength", "Maximum2DDiameterRow", "Maximum2DDiameterSlice", "MeshVolume", "SizeZoneNonUniformity", "SmallDependenceHighGrayLevelEmphasis", "SurfaceArea", "TotalEnergy", "VoxelVolume")

imgFeatTableF <- imgFeatTable[features, ]
imgFeatTableF
load("./analysis_SF/allRawCorrs.RData")

filterCorr <- function(corTable, th = 0.6) {
  return(as.data.frame(corTable[,colSums((corTable > th) | (corTable < -th))> 0]))
}

corrIfTpF <- filterCorr(corrIfTp[features,], 0.5) # 0.5
tumSelected <- paste0(colnames(corrIfTpF), "_T")
print(length(tumSelected))
[1] 8
tumProtTableF <- tumProtTable[tumSelected,]
corrIfNpF <- filterCorr(corrIfNp[features,], 0.6) # 0.6
normSelected <- paste0(colnames(corrIfNpF), "_N")
print(length(normSelected))
[1] 18
normProtTableF <- normProtTable[normSelected,]
tumProtTableF
normProtTableF
col_names <- Reduce(intersect, list(colnames(imgFeatTableF), colnames(tumProtTableF), colnames(normProtTableF), colnames(lnTableF)))
imgFeatProtTable <- data.frame(t(data.frame(rbind(imgFeatTableF[, col_names], tumProtTableF[, col_names], normProtTableF[, col_names], lnTableF[, col_names]))))
imgFeatProtTable
rho = cor(imgFeatProtTable)
heatmap.2(rho, scale = "none", trace = "none", revC = TRUE)#, breaks = palette.breaks)

ug = empty.graph(colnames(rho))
amat(ug) = (rho > 0.6) + 0L - diag(1L, nrow(rho))
graphviz.plot(ug, layout = "fdp", shape = "ellipse")

bl <- rbind(
    set2blacklist(c(rownames(tumProtTableF), rownames(normProtTableF))), 
    set2blacklist(rownames(lnTableF)), 
    set2blacklist(rownames(imgFeatTableF)), 
    tiers2blacklist(list(c(rownames(tumProtTableF), rownames(normProtTableF)),  
                         rownames(imgFeatTableF))), 
    tiers2blacklist(list(rownames(lnTableF), rownames(imgFeatTableF))),
    tiers2blacklist(list(c(rownames(tumProtTableF), rownames(normProtTableF)), 
                         rownames(lnTableF)))#,
    # tiers2blacklist(list(c(rownames(tumProtTableF), rownames(normProtTableF)), 
    #                      rownames(imgFeatTableF)))
    )
wl <- rbind(
    tiers2blacklist(list(rownames(lnTableF), 
                         c(rownames(tumProtTableF), rownames(normProtTableF)))),
    # tiers2blacklist(list(rownames(imgFeatTableF), 
    #                      c(rownames(tumProtTableF), rownames(normProtTableF)))),
    tiers2blacklist(list(rownames(imgFeatTableF), rownames(lnTableF)))
    )
str.raw = boot.strength(imgFeatProtTable, R = 100, algorithm = "hc", algorithm.args = list(blacklist = bl, whitelist = wl))
attr(str.raw, "threshold")
[1] 0.5
avg.raw.full = averaged.network(str.raw)
strength.plot(avg.raw.full, str.raw, shape = "ellipse")#, highlight = list(arcs = wl))

strength.plot(avg.raw.full, str.raw, threshold = 0.85, shape = "ellipse")#, highlight = list(arcs = wl))


avg.raw.full$learning$whitelist = wl
avg.raw.full$learning$blacklist = bl
nrow(undirected.arcs(cpdag(avg.raw.full, wlbl = TRUE)))
[1] 0
nrow(str.raw[with(str.raw, strength > 0.50 & direction > 0.50), ])
[1] 261
nrow(str.raw[with(str.raw, strength > 0.85 & direction > 0.50), ])
[1] 78
min(str.raw[with(str.raw, strength > 0.50 & direction > 0.50), "direction"])
[1] 1
avg.raw.simpler = averaged.network(str.raw, threshold = 0.8)
g <- Rgraphviz::layoutGraph(bnlearn::as.graphNEL(avg.raw.simpler))
graph::nodeRenderInfo(g) <- list(fontsize=100)
Rgraphviz::renderGraph(g)

strength.plot(avg.raw.simpler, str.raw, shape = "ellipse")#, highlight = list(arcs = wl))

dag = hc(imgFeatProtTable, whitelist = wl, blacklist = bl)
dag

  Bayesian network learned via Score-based methods

  model:
   [DCUN1D1_T][EIF4H_T][KRAS_T][MLF2_T][PDAP1_T][PUM1_T][SUMF2_T][USP30_T][ATP8A1_N][ATP9B_N][CDC25B_N][CDK14_N][COL21A1_N][DTD2_N][ERP44_N]
   [FAM171A2_N][FAM204A_N][GORASP2_N][IAH1_N][NCEH1_N][PDE3A_N][PHLPP1_N][PLEKHA3_N][RPL9_N][SPN_N][STK39_N]
   [affected|DCUN1D1_T:EIF4H_T:KRAS_T:MLF2_T:PDAP1_T:PUM1_T:SUMF2_T:USP30_T:ATP8A1_N:ATP9B_N:CDC25B_N:CDK14_N:COL21A1_N:DTD2_N:ERP44_N:FAM171A2_N:FAM204A_N:GORASP2_N:IAH1_N:NCEH1_N:PDE3A_N:PHLPP1_N:PLEKHA3_N:RPL9_N:SPN_N:STK39_N]
   [NoLN|DCUN1D1_T:EIF4H_T:KRAS_T:MLF2_T:PDAP1_T:PUM1_T:SUMF2_T:USP30_T:ATP8A1_N:ATP9B_N:CDC25B_N:CDK14_N:COL21A1_N:DTD2_N:ERP44_N:FAM171A2_N:FAM204A_N:GORASP2_N:IAH1_N:NCEH1_N:PDE3A_N:PHLPP1_N:PLEKHA3_N:RPL9_N:SPN_N:STK39_N]
   [Complexity|KRAS_T:USP30_T:RPL9_N:affected:NoLN][InterquartileRange|KRAS_T:STK39_N:affected:NoLN]
   [LeastAxisLength|MLF2_T:USP30_T:ATP8A1_N:ATP9B_N:IAH1_N:SPN_N:affected:NoLN]
   [MajorAxisLength|DCUN1D1_T:KRAS_T:MLF2_T:SUMF2_T:USP30_T:ATP9B_N:CDC25B_N:DTD2_N:ERP44_N:NCEH1_N:SPN_N:STK39_N:affected:NoLN]
   [Maximum2DDiameterRow|USP30_T:COL21A1_N:NCEH1_N:RPL9_N:affected:NoLN]
   [Maximum2DDiameterSlice|DCUN1D1_T:USP30_T:ATP9B_N:DTD2_N:ERP44_N:SPN_N:STK39_N:affected:NoLN]
   [MeshVolume|MLF2_T:ATP8A1_N:FAM171A2_N:IAH1_N:PLEKHA3_N:RPL9_N:affected:NoLN]
   [SizeZoneNonUniformity|DCUN1D1_T:KRAS_T:PDAP1_T:PUM1_T:USP30_T:DTD2_N:PHLPP1_N:PLEKHA3_N:RPL9_N:STK39_N:affected:NoLN]
   [SmallDependenceHighGrayLevelEmphasis|DCUN1D1_T:KRAS_T:PDAP1_T:USP30_T:PHLPP1_N:affected:NoLN]
   [SurfaceArea|USP30_T:ERP44_N:FAM171A2_N:IAH1_N:SPN_N:affected:NoLN][TotalEnergy|COL21A1_N:PLEKHA3_N:RPL9_N:affected:NoLN]
   [VoxelVolume|MLF2_T:ATP8A1_N:FAM171A2_N:IAH1_N:PLEKHA3_N:RPL9_N:affected:NoLN]
  nodes:                                 40 
  arcs:                                  145 
    undirected arcs:                     0 
    directed arcs:                       145 
  average markov blanket size:           23.55 
  average neighbourhood size:            7.25 
  average branching factor:              3.62 

  learning algorithm:                    Hill-Climbing 
  score:                                 BIC (Gauss.) 
  penalization coefficient:              1.76318 
  tests used in the learning procedure:  2600 
  optimized:                             TRUE 
str.raw = boot.strength(imgFeatProtTable, R = 100, algorithm = "hc")#, algorithm.args = list(blacklist = bl, whitelist = wl))
attr(str.raw, "threshold")
[1] 0.5
avg.raw.full = averaged.network(str.raw)
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc TotalEnergy -> PLEKHA3_N would introduce cycles in the graph, ignoring.
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc COL21A1_N -> FAM171A2_N would introduce cycles in the graph, ignoring.
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc SurfaceArea -> LeastAxisLength would introduce cycles in the graph, ignoring.
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc COL21A1_N -> PLEKHA3_N would introduce cycles in the graph, ignoring.
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc SUMF2_T -> KRAS_T would introduce cycles in the graph, ignoring.
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc COL21A1_N -> PDE3A_N would introduce cycles in the graph, ignoring.
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc MeshVolume -> TotalEnergy would introduce cycles in the graph, ignoring.
Warning in averaged.network.backend(strength = strength, threshold = threshold) :
  arc MeshVolume -> VoxelVolume would introduce cycles in the graph, ignoring.
strength.plot(avg.raw.full, str.raw, shape = "ellipse")#, highlight = list(arcs = wl))

xval = bn.cv(imgFeatProtTable, bn = "hc", algorithm.args = list(blacklist = bl, whitelist = wl), loss = "cor-lw", loss.args = list(target = "affected", n = 200), runs = 10)
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero
Warning in cor(data[, node], pred) : the standard deviation is zero

Compare different models and features

col_names <- Reduce(intersect, list(colnames(imgFeatTableF), colnames(tumProtTableF), colnames(normProtTableF), colnames(lnTableF)))

img_prot_af <- data.frame(t(data.frame(rbind(imgFeatTableF[, col_names], tumProtTableF[, col_names], normProtTableF[, col_names], lnAfTableF[, col_names]))))
img_tum_af <- data.frame(t(data.frame(rbind(imgFeatTableF[, col_names], tumProtTableF[, col_names], lnAfTableF[, col_names]))))
img_norm_af <- data.frame(t(data.frame(rbind(imgFeatTableF[, col_names], normProtTableF[, col_names], lnAfTableF[, col_names]))))
img_af <- data.frame(t(data.frame(rbind(imgFeatTableF[, col_names], lnAfTableF[, col_names]))))
prot_af <- data.frame(t(data.frame(rbind(tumProtTableF[, col_names], normProtTableF[, col_names], lnAfTableF[, col_names]))))

img_prot_no <- data.frame(t(data.frame(rbind(imgFeatTableF[, col_names], tumProtTableF[, col_names], normProtTableF[, col_names], lnNoTableF[, col_names]))))
img_no <- data.frame(t(data.frame(rbind(imgFeatTableF[, col_names], lnNoTableF[, col_names]))))
prot_no <- data.frame(t(data.frame(rbind(tumProtTableF[, col_names], normProtTableF[, col_names], lnNoTableF[, col_names]))))
bn_img_af <- empty.graph(c(rownames(imgFeatTableF), rownames(lnAfTableF)))
wl_img_af <- tiers2blacklist(list(rownames(lnAfTableF), rownames(imgFeatTableF)))
arcs(bn_img_af) <- wl_img_af

bn_prot_af <- empty.graph(c(rownames(tumProtTableF), rownames(normProtTableF), rownames(lnAfTableF)))
wl_prot_af <- tiers2blacklist(list(rownames(lnAfTableF), c(rownames(tumProtTableF), rownames(normProtTableF))))
arcs(bn_prot_af) <- wl_prot_af

bn_prot_img_af <- empty.graph(c(rownames(imgFeatTableF), rownames(tumProtTableF), rownames(normProtTableF), rownames(lnAfTableF)))
wl_prot_img_af <- rbind(
  tiers2blacklist(list(rownames(lnAfTableF), rownames(imgFeatTableF))),
  tiers2blacklist(list(rownames(imgFeatTableF), c(rownames(tumProtTableF), rownames(normProtTableF))))
)
arcs(bn_prot_img_af) <- wl_prot_img_af

bn_tum_img_af <- empty.graph(c(rownames(imgFeatTableF), rownames(tumProtTableF), rownames(lnAfTableF)))
wl_tum_img_af <- rbind(
  tiers2blacklist(list(rownames(lnAfTableF), rownames(imgFeatTableF))),
  tiers2blacklist(list(rownames(imgFeatTableF), c(rownames(tumProtTableF))))
)
arcs(bn_tum_img_af) <- wl_tum_img_af

bn_norm_img_af <- empty.graph(c(rownames(imgFeatTableF), rownames(normProtTableF), rownames(lnAfTableF)))
wl_norm_img_af <- rbind(
  tiers2blacklist(list(rownames(lnAfTableF), rownames(imgFeatTableF))),
  tiers2blacklist(list(rownames(imgFeatTableF), rownames(normProtTableF)))
)
arcs(bn_norm_img_af) <- wl_norm_img_af

bn_prot_img_id_af <- empty.graph(c(rownames(imgFeatTableF), rownames(tumProtTableF), rownames(normProtTableF), rownames(lnAfTableF)))
wl_prot_img_id_af <- tiers2blacklist(list(rownames(lnAfTableF), c(rownames(imgFeatTableF), rownames(tumProtTableF), rownames(normProtTableF))))
arcs(bn_prot_img_id_af) <- wl_prot_img_id_af
bn_img_no <- empty.graph(c(rownames(imgFeatTableF), rownames(lnNoTableF)))
wl_img_no <- tiers2blacklist(list(rownames(lnNoTableF), rownames(imgFeatTableF)))
arcs(bn_img_no) <- wl_img_no
bn_prot_no <- empty.graph(c(rownames(tumProtTableF), rownames(normProtTableF), rownames(lnNoTableF)))
wl_prot_no <- tiers2blacklist(list(rownames(lnNoTableF), c(rownames(tumProtTableF), rownames(normProtTableF))))
arcs(bn_prot_no) <- wl_prot_no
bn_prot_img_no <- empty.graph(c(rownames(imgFeatTableF), rownames(tumProtTableF), rownames(normProtTableF), rownames(lnNoTableF)))
wl_prot_img_no <- rbind(
  tiers2blacklist(list(rownames(lnNoTableF), rownames(imgFeatTableF))),
  tiers2blacklist(list(rownames(imgFeatTableF), c(rownames(tumProtTableF), rownames(normProtTableF))))
)
arcs(bn_prot_img_no) <- wl_prot_img_no
bn_prot_img_id_no <- empty.graph(c(rownames(imgFeatTableF), rownames(tumProtTableF), rownames(normProtTableF), rownames(lnNoTableF)))
wl_prot_img_id_no <- tiers2blacklist(list(rownames(lnNoTableF), c(rownames(imgFeatTableF), rownames(tumProtTableF), rownames(normProtTableF))))
arcs(bn_prot_img_id_no) <- wl_prot_img_id_no
graphviz.plot(bn_img_af)

graphviz.plot(bn_prot_af)

graphviz.plot(bn_prot_img_af)

graphviz.plot(bn_prot_img_id_af)

graphviz.plot(bn_tum_img_af)

graphviz.plot(bn_norm_img_af)

img_af_cv <- bn.cv(img_af, bn = bn_img_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
prot_af_cv <- bn.cv(prot_af, bn = bn_prot_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_prot_af_cv <- bn.cv(img_prot_af, bn = bn_prot_img_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_tum_af_cv <- bn.cv(img_tum_af, bn = bn_tum_img_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_norm_af_cv <- bn.cv(img_norm_af, bn = bn_norm_img_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_prot_id_af_cv <- bn.cv(img_prot_af, bn = bn_prot_img_id_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
plot(img_af_cv, prot_af_cv, img_prot_af_cv, img_tum_af_cv, img_norm_af_cv, img_prot_id_af_cv, xlab = c("Image only", "Proteomics only", "Proteomics -> Image", "Tum prot -> Image", "Norm prot -> Image", "Image + Proteomics"))
par(las=2)

plot(img_af_cv, img_prot_af_cv, xlab = c("Image only", "Proteomics -> Image"))

plot(img_af_cv, img_prot_af_cv, img_tum_af_cv, img_norm_af_cv, xlab = c("Image only", "Proteomics -> Image", "Tum prot -> Image", "Norm prot -> Image"))

save(img_af_cv, prot_af_cv, img_prot_af_cv, img_tum_af_cv, img_norm_af_cv, img_prot_id_af_cv, file = "./analysis_SF/comparisons.RData")

valid learning algorithm(s) are “gs” (Grow-Shrink), “iamb” (IAMB), “fast.iamb” (Fast-IAMB), “inter.iamb” (Inter-IAMB), “iamb.fdr” (IAMB-FDR), “pc.stable” (PC (Stable)), “mmpc” (Max-Min Parent Children), “si.hiton.pc” (Semi-Interleaved HITON-PC), “hpc” (Hybrid Parents and Children), “hc” (Hill-Climbing), “tabu” (Tabu Search), “rsmax2” (Two-Phase Restricted Maximization), “mmhc” (Max-Min Hill-Climbing), “h2pc” (Hybrid^2 Parent Children), “chow.liu” (Chow-Liu), “aracne” (ARACNE), “naive.bayes” (Naive Bayes Classifier), “tree.bayes” (TAN Bayes Classifier). See ?bnlearn-package for details.

img_af_ho <- bn.cv(img_af, bn = bn_img_af, runs = 10, method = "hold-out", k = 10, m = 10, loss = "mse-lw", loss.args = list(target = "affected"))
prot_af_ho <- bn.cv(prot_af, bn = bn_prot_af, runs = 10, method = "hold-out", k = 10, m = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_prot_af_ho <- bn.cv(img_prot_af, bn = bn_prot_img_af, runs = 10, method = "hold-out", k = 10, m = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_tum_af_ho <- bn.cv(img_tum_af, bn = bn_tum_img_af, runs = 10, method = "hold-out", k = 10, m = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_norm_af_ho <- bn.cv(img_norm_af, bn = bn_norm_img_af, runs = 10, method = "hold-out", k = 10, m = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_prot_id_af_ho <- bn.cv(img_prot_af, bn = bn_prot_img_id_af, runs = 10, method = "hold-out", k = 10, m = 10, loss = "mse-lw", loss.args = list(target = "affected"))
plot(img_af_ho, prot_af_ho, img_prot_af_ho, img_tum_af_ho, img_norm_af_ho, img_prot_id_af_ho, xlab = c("Image only", "Proteomics only", "Proteomics -> Image", "Tum prot -> Image", "Norm prot -> Image", "Image + Proteomics"))
plot(img_af_ho, img_prot_af_ho, xlab = c("Image only", "Proteomics -> Image"))
plot(img_af_ho, img_prot_af_ho, img_tum_af_ho, img_norm_af_ho, xlab = c("Image only", "Proteomics -> Image", "Tum prot -> Image", "Norm prot -> Image"))
img_af_cv <- bn.cv(img_af, bn = bn_img_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
prot_af_cv <- bn.cv(prot_af, bn = bn_prot_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_prot_af_cv <- bn.cv(img_prot_af, bn = bn_prot_img_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
img_prot_id_af_cv <- bn.cv(img_prot_af, bn = bn_prot_img_id_af, runs = 10, loss = "mse-lw", loss.args = list(target = "affected"))
plot(img_af_cv, prot_af_cv, img_prot_af_cv, img_prot_id_af_cv, xlab = c("Image only", "Proteomics only", "Proteomics -> Image", "Image + Proteomics"))
plot(img_af_cv, img_prot_af_cv, xlab = c("Image only", "Proteomics -> Image"))
img_af_cv <- bn.cv(img_af, bn = bn_img_af, runs = 10, loss = "mse", loss.args = list(target = "affected"))
prot_af_cv <- bn.cv(prot_af, bn = bn_prot_af, runs = 10, loss = "mse", loss.args = list(target = "affected"))
img_prot_af_cv <- bn.cv(img_prot_af, bn = bn_prot_img_af, runs = 10, loss = "mse", loss.args = list(target = "affected"))
img_prot_id_af_cv <- bn.cv(img_prot_af, bn = bn_prot_img_id_af, runs = 10, loss = "mse", loss.args = list(target = "affected"))
plot(img_af_cv, prot_af_cv, img_prot_af_cv, img_prot_id_af_cv, xlab = c("Image only", "Proteomics only", "Proteomics -> Image", "Image + Proteomics"))
plot(img_af_cv, img_prot_af_cv, xlab = c("Image only", "Proteomics -> Image"))
img_no_cv <- bn.cv(img_no, bn = bn_img_no, runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
prot_no_cv <- bn.cv(prot_no, bn = bn_prot_no, runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
img_prot_no_cv <- bn.cv(img_prot_no, bn = bn_prot_img_no, runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
img_prot_id_no_cv <- bn.cv(img_prot_no, bn = bn_prot_img_id_no, runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
plot(img_no_cv, prot_no_cv, img_prot_no_cv, img_prot_id_no_cv, xlab = c("Image only", "Proteomics only", "Proteomics -> Image", "Image + Proteomics"))
plot(img_no_cv, img_prot_no_cv, xlab = c("Image only", "Proteomics -> Image"))

Tests

img_af_cv <- bn.cv(img_af, bn = "hc", runs = 10, loss = "mse", loss.args = list(target = "affected"))
prot_af_cv <- bn.cv(prot_af, bn = "hc", runs = 10, loss = "mse", loss.args = list(target = "affected"))
img_prot_af_cv <- bn.cv(img_prot_af, bn = "hc", runs = 10, loss = "mse", loss.args = list(target = "affected"))
plot(img_af_cv, prot_af_cv, img_prot_af_cv, xlab = c("Image only", "Proteomics only", "Image + Proteomics"))
img_no_cv <- bn.cv(img_no, bn = "tabu", runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
prot_no_cv <- bn.cv(prot_no, bn = "tabu", runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
img_prot_no_cv <- bn.cv(img_prot_no, bn = "tabu", runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
plot(img_no_cv, prot_no_cv, img_prot_no_cv, xlab = c("Image only", "Proteomics only", "Image + Proteomics"))
img_no_cv <- bn.cv(img_no, bn = "hc", runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
prot_no_cv <- bn.cv(prot_no, bn = "hc", runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
img_prot_no_cv <- bn.cv(img_prot_no, bn = "hc", runs = 10, loss = "mse", loss.args = list(target = "NoLN"))
plot(img_no_cv, prot_no_cv, img_prot_no_cv, xlab = c("Image only", "Proteomics only", "Image + Proteomics"))

Using other models to do the cross validation, like AutoML?

Hidden Markov Model for modeling the lymphinode dynamics

LS0tCnRpdGxlOiAiQnVpbGQgdXAgdGhlIEJheWVzaWFuIG5ldHdvcmsiCmF1dGhvcjogIlNvbmcgRmVuZyIKZGF0ZTogIjA4LzA3LzIwMjEiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmxvYWRpbmcgdGhlIHBhY2thZ2UKCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ3Bsb3RzKQpsaWJyYXJ5KGJubGVhcm4pCmBgYAoKTG9hZCB0aGUgZGF0YQoKYGBge3J9CnNvdXJjZSgnbG9hZEhOU0NDZGF0YS5SJykKbGlicmFyeShyZXNoYXBlKQp0dW1Qcm90VGFibGUgPC0gY2FzdCh0dW1Qcm90cywgR2VuZX5wYXRpZW50LCBtZWFuKQpyb3duYW1lcyh0dW1Qcm90VGFibGUpIDwtIHBhc3RlMCh0dW1Qcm90VGFibGUkR2VuZSwgIl9UIikKdHVtUHJvdFRhYmxlJEdlbmUgPC0gTlVMTApub3JtUHJvdFRhYmxlIDwtIGNhc3Qobm9ybVByb3RzLCBHZW5lfnBhdGllbnQsIG1lYW4pCnJvd25hbWVzKG5vcm1Qcm90VGFibGUpIDwtIHBhc3RlMChub3JtUHJvdFRhYmxlJEdlbmUsICJfTiIpCm5vcm1Qcm90VGFibGUkR2VuZSA8LSBOVUxMCmltZ0ZlYXRUYWJsZSA8LSBjYXN0KGltZ0ZlYXQsIEZlYXR1cmVfVHlwZX5wYXRpZW50LCBtZWFuKQpyb3duYW1lcyhpbWdGZWF0VGFibGUpIDwtIGltZ0ZlYXRUYWJsZSRGZWF0dXJlX1R5cGUKaW1nRmVhdFRhYmxlJEZlYXR1cmVfVHlwZSA8LSBOVUxMCgpsblRhYmxlQWxsIDwtIHJlZC5kYXQKbG5UYWJsZUFsbCRhZmZlY3RlZCA8LSBhYnModW5jbGFzcyhmYWN0b3IobG5UYWJsZUFsbCRsblNwcmVhZCkpIC0gMikKbG5UYWJsZUFsbCROb0xOIDwtIGFicyh1bmNsYXNzKGZhY3RvcihsblRhYmxlQWxsJGxuQ291bnRzKSkgLSAzKQpsblRhYmxlIDwtIGFzLmRhdGEuZnJhbWUobG5UYWJsZUFsbFsgLGMoInBhdGllbnQiLCAiYWZmZWN0ZWQiLCAiTm9MTiIpXSkKbG5BZlRhYmxlIDwtIGFzLmRhdGEuZnJhbWUobG5UYWJsZUFsbFsgLGMoInBhdGllbnQiLCAiYWZmZWN0ZWQiKV0pCmxuTm9UYWJsZSA8LSBhcy5kYXRhLmZyYW1lKGxuVGFibGVBbGxbICxjKCJwYXRpZW50IiwgIk5vTE4iKV0pCgpyb3duYW1lcyhsblRhYmxlKSA8LSBsblRhYmxlJHBhdGllbnQKcm93bmFtZXMobG5BZlRhYmxlKSA8LSBsblRhYmxlJHBhdGllbnQgCnJvd25hbWVzKGxuTm9UYWJsZSkgPC0gbG5UYWJsZSRwYXRpZW50CmxuVGFibGUkcGF0aWVudCA8LSBOVUxMIApsbkFmVGFibGUkcGF0aWVudCA8LSBOVUxMIApsbk5vVGFibGUkcGF0aWVudCA8LSBOVUxMCmxuVGFibGVGIDwtIGFzLmRhdGEuZnJhbWUodChsblRhYmxlKSkKbG5BZlRhYmxlRiA8LSBhcy5kYXRhLmZyYW1lKHQobG5BZlRhYmxlKSkKbG5Ob1RhYmxlRiA8LSBhcy5kYXRhLmZyYW1lKHQobG5Ob1RhYmxlKSkKYGBgCgoKYGBge3J9CmxvYWQoIi4vYW5hbHlzaXNfU0YvYWxsQ29ycnMuUkRhdGEiKQpgYGAKCmBgYHtyfQpmZWF0dXJlcyA8LSBjKCJDb21wbGV4aXR5IiwgIkludGVycXVhcnRpbGVSYW5nZSIsICJMZWFzdEF4aXNMZW5ndGgiLCAiTWFqb3JBeGlzTGVuZ3RoIiwgIk1heGltdW0yRERpYW1ldGVyUm93IiwgIk1heGltdW0yRERpYW1ldGVyU2xpY2UiLCAiTWVzaFZvbHVtZSIsICJTaXplWm9uZU5vblVuaWZvcm1pdHkiLCAiU21hbGxEZXBlbmRlbmNlSGlnaEdyYXlMZXZlbEVtcGhhc2lzIiwgIlN1cmZhY2VBcmVhIiwgIlRvdGFsRW5lcmd5IiwgIlZveGVsVm9sdW1lIikKCmltZ0ZlYXRUYWJsZUYgPC0gaW1nRmVhdFRhYmxlW2ZlYXR1cmVzLCBdCmltZ0ZlYXRUYWJsZUYKYGBgCgoKYGBge3J9CmxvYWQoIi4vYW5hbHlzaXNfU0YvYWxsUmF3Q29ycnMuUkRhdGEiKQoKZmlsdGVyQ29yciA8LSBmdW5jdGlvbihjb3JUYWJsZSwgdGggPSAwLjYpIHsKICByZXR1cm4oYXMuZGF0YS5mcmFtZShjb3JUYWJsZVssY29sU3VtcygoY29yVGFibGUgPiB0aCkgfCAoY29yVGFibGUgPCAtdGgpKT4gMF0pKQp9Cgpjb3JySWZUcEYgPC0gZmlsdGVyQ29ycihjb3JySWZUcFtmZWF0dXJlcyxdLCAwLjUpICMgMC41CnR1bVNlbGVjdGVkIDwtIHBhc3RlMChjb2xuYW1lcyhjb3JySWZUcEYpLCAiX1QiKQpwcmludChsZW5ndGgodHVtU2VsZWN0ZWQpKQp0dW1Qcm90VGFibGVGIDwtIHR1bVByb3RUYWJsZVt0dW1TZWxlY3RlZCxdCmNvcnJJZk5wRiA8LSBmaWx0ZXJDb3JyKGNvcnJJZk5wW2ZlYXR1cmVzLF0sIDAuNikgIyAwLjYKbm9ybVNlbGVjdGVkIDwtIHBhc3RlMChjb2xuYW1lcyhjb3JySWZOcEYpLCAiX04iKQpwcmludChsZW5ndGgobm9ybVNlbGVjdGVkKSkKbm9ybVByb3RUYWJsZUYgPC0gbm9ybVByb3RUYWJsZVtub3JtU2VsZWN0ZWQsXQpgYGAKCmBgYHtyfQp0dW1Qcm90VGFibGVGCmBgYAoKYGBge3J9Cm5vcm1Qcm90VGFibGVGCmBgYAoKCgpgYGB7cn0KY29sX25hbWVzIDwtIFJlZHVjZShpbnRlcnNlY3QsIGxpc3QoY29sbmFtZXMoaW1nRmVhdFRhYmxlRiksIGNvbG5hbWVzKHR1bVByb3RUYWJsZUYpLCBjb2xuYW1lcyhub3JtUHJvdFRhYmxlRiksIGNvbG5hbWVzKGxuVGFibGVGKSkpCmltZ0ZlYXRQcm90VGFibGUgPC0gZGF0YS5mcmFtZSh0KGRhdGEuZnJhbWUocmJpbmQoaW1nRmVhdFRhYmxlRlssIGNvbF9uYW1lc10sIHR1bVByb3RUYWJsZUZbLCBjb2xfbmFtZXNdLCBub3JtUHJvdFRhYmxlRlssIGNvbF9uYW1lc10sIGxuVGFibGVGWywgY29sX25hbWVzXSkpKSkKaW1nRmVhdFByb3RUYWJsZQpgYGAKCgpgYGB7cn0KcmhvID0gY29yKGltZ0ZlYXRQcm90VGFibGUpCmhlYXRtYXAuMihyaG8sIHNjYWxlID0gIm5vbmUiLCB0cmFjZSA9ICJub25lIiwgcmV2QyA9IFRSVUUpIywgYnJlYWtzID0gcGFsZXR0ZS5icmVha3MpCmBgYAoKYGBge3J9CnVnID0gZW1wdHkuZ3JhcGgoY29sbmFtZXMocmhvKSkKYW1hdCh1ZykgPSAocmhvID4gMC42KSArIDBMIC0gZGlhZygxTCwgbnJvdyhyaG8pKQpncmFwaHZpei5wbG90KHVnLCBsYXlvdXQgPSAiZmRwIiwgc2hhcGUgPSAiZWxsaXBzZSIpCmBgYAoKYGBge3J9CmJsIDwtIHJiaW5kKAogICAgc2V0MmJsYWNrbGlzdChjKHJvd25hbWVzKHR1bVByb3RUYWJsZUYpLCByb3duYW1lcyhub3JtUHJvdFRhYmxlRikpKSwgCiAgICBzZXQyYmxhY2tsaXN0KHJvd25hbWVzKGxuVGFibGVGKSksIAogICAgc2V0MmJsYWNrbGlzdChyb3duYW1lcyhpbWdGZWF0VGFibGVGKSksIAogICAgdGllcnMyYmxhY2tsaXN0KGxpc3QoYyhyb3duYW1lcyh0dW1Qcm90VGFibGVGKSwgcm93bmFtZXMobm9ybVByb3RUYWJsZUYpKSwgIAogICAgICAgICAgICAgICAgICAgICAgICAgcm93bmFtZXMoaW1nRmVhdFRhYmxlRikpKSwgCiAgICB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhsblRhYmxlRiksIHJvd25hbWVzKGltZ0ZlYXRUYWJsZUYpKSksCiAgICB0aWVyczJibGFja2xpc3QobGlzdChjKHJvd25hbWVzKHR1bVByb3RUYWJsZUYpLCByb3duYW1lcyhub3JtUHJvdFRhYmxlRikpLCAKICAgICAgICAgICAgICAgICAgICAgICAgIHJvd25hbWVzKGxuVGFibGVGKSkpIywKICAgICMgdGllcnMyYmxhY2tsaXN0KGxpc3QoYyhyb3duYW1lcyh0dW1Qcm90VGFibGVGKSwgcm93bmFtZXMobm9ybVByb3RUYWJsZUYpKSwgCiAgICAjICAgICAgICAgICAgICAgICAgICAgIHJvd25hbWVzKGltZ0ZlYXRUYWJsZUYpKSkKICAgICkKd2wgPC0gcmJpbmQoCiAgICB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhsblRhYmxlRiksIAogICAgICAgICAgICAgICAgICAgICAgICAgYyhyb3duYW1lcyh0dW1Qcm90VGFibGVGKSwgcm93bmFtZXMobm9ybVByb3RUYWJsZUYpKSkpLAogICAgIyB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhpbWdGZWF0VGFibGVGKSwgCiAgICAjICAgICAgICAgICAgICAgICAgICAgIGMocm93bmFtZXModHVtUHJvdFRhYmxlRiksIHJvd25hbWVzKG5vcm1Qcm90VGFibGVGKSkpKSwKICAgIHRpZXJzMmJsYWNrbGlzdChsaXN0KHJvd25hbWVzKGltZ0ZlYXRUYWJsZUYpLCByb3duYW1lcyhsblRhYmxlRikpKQogICAgKQpgYGAKCgoKCmBgYHtyfQpzdHIucmF3ID0gYm9vdC5zdHJlbmd0aChpbWdGZWF0UHJvdFRhYmxlLCBSID0gMTAwLCBhbGdvcml0aG0gPSAiaGMiLCBhbGdvcml0aG0uYXJncyA9IGxpc3QoYmxhY2tsaXN0ID0gYmwsIHdoaXRlbGlzdCA9IHdsKSkKYXR0cihzdHIucmF3LCAidGhyZXNob2xkIikKYXZnLnJhdy5mdWxsID0gYXZlcmFnZWQubmV0d29yayhzdHIucmF3KQpgYGAKCmBgYHtyfQpzdHJlbmd0aC5wbG90KGF2Zy5yYXcuZnVsbCwgc3RyLnJhdywgc2hhcGUgPSAiZWxsaXBzZSIpIywgaGlnaGxpZ2h0ID0gbGlzdChhcmNzID0gd2wpKQpgYGAKCmBgYHtyfQpzdHJlbmd0aC5wbG90KGF2Zy5yYXcuZnVsbCwgc3RyLnJhdywgdGhyZXNob2xkID0gMC44NSwgc2hhcGUgPSAiZWxsaXBzZSIpIywgaGlnaGxpZ2h0ID0gbGlzdChhcmNzID0gd2wpKQpgYGAKCgpgYGB7cn0KCmF2Zy5yYXcuZnVsbCRsZWFybmluZyR3aGl0ZWxpc3QgPSB3bAphdmcucmF3LmZ1bGwkbGVhcm5pbmckYmxhY2tsaXN0ID0gYmwKbnJvdyh1bmRpcmVjdGVkLmFyY3MoY3BkYWcoYXZnLnJhdy5mdWxsLCB3bGJsID0gVFJVRSkpKQpgYGAKCmBgYHtyfQpucm93KHN0ci5yYXdbd2l0aChzdHIucmF3LCBzdHJlbmd0aCA+IDAuNTAgJiBkaXJlY3Rpb24gPiAwLjUwKSwgXSkKYGBgCgpgYGB7cn0KbnJvdyhzdHIucmF3W3dpdGgoc3RyLnJhdywgc3RyZW5ndGggPiAwLjg1ICYgZGlyZWN0aW9uID4gMC41MCksIF0pCmBgYAoKCmBgYHtyfQptaW4oc3RyLnJhd1t3aXRoKHN0ci5yYXcsIHN0cmVuZ3RoID4gMC41MCAmIGRpcmVjdGlvbiA+IDAuNTApLCAiZGlyZWN0aW9uIl0pCmBgYAoKCmBgYHtyfQphdmcucmF3LnNpbXBsZXIgPSBhdmVyYWdlZC5uZXR3b3JrKHN0ci5yYXcsIHRocmVzaG9sZCA9IDAuOCkKZyA8LSBSZ3JhcGh2aXo6OmxheW91dEdyYXBoKGJubGVhcm46OmFzLmdyYXBoTkVMKGF2Zy5yYXcuc2ltcGxlcikpCmdyYXBoOjpub2RlUmVuZGVySW5mbyhnKSA8LSBsaXN0KGZvbnRzaXplPTEwMCkKUmdyYXBodml6OjpyZW5kZXJHcmFwaChnKQpzdHJlbmd0aC5wbG90KGF2Zy5yYXcuc2ltcGxlciwgc3RyLnJhdywgc2hhcGUgPSAiZWxsaXBzZSIpIywgaGlnaGxpZ2h0ID0gbGlzdChhcmNzID0gd2wpKQpgYGAKCmBgYHtyfQpkYWcgPSBoYyhpbWdGZWF0UHJvdFRhYmxlLCB3aGl0ZWxpc3QgPSB3bCwgYmxhY2tsaXN0ID0gYmwpCmRhZwpgYGAKCmBgYHtyfQpzdHIucmF3ID0gYm9vdC5zdHJlbmd0aChpbWdGZWF0UHJvdFRhYmxlLCBSID0gMTAwLCBhbGdvcml0aG0gPSAiaGMiKSMsIGFsZ29yaXRobS5hcmdzID0gbGlzdChibGFja2xpc3QgPSBibCwgd2hpdGVsaXN0ID0gd2wpKQphdHRyKHN0ci5yYXcsICJ0aHJlc2hvbGQiKQphdmcucmF3LmZ1bGwgPSBhdmVyYWdlZC5uZXR3b3JrKHN0ci5yYXcpCmBgYAoKYGBge3J9CnN0cmVuZ3RoLnBsb3QoYXZnLnJhdy5mdWxsLCBzdHIucmF3LCBzaGFwZSA9ICJlbGxpcHNlIikjLCBoaWdobGlnaHQgPSBsaXN0KGFyY3MgPSB3bCkpCmBgYAoKYGBge3J9Cnh2YWwgPSBibi5jdihpbWdGZWF0UHJvdFRhYmxlLCBibiA9ICJoYyIsIGFsZ29yaXRobS5hcmdzID0gbGlzdChibGFja2xpc3QgPSBibCwgd2hpdGVsaXN0ID0gd2wpLCBsb3NzID0gImNvci1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIiwgbiA9IDIwMCksIHJ1bnMgPSAxMCkKYGBgCgojIENvbXBhcmUgZGlmZmVyZW50IG1vZGVscyBhbmQgZmVhdHVyZXMKCmBgYHtyfQpjb2xfbmFtZXMgPC0gUmVkdWNlKGludGVyc2VjdCwgbGlzdChjb2xuYW1lcyhpbWdGZWF0VGFibGVGKSwgY29sbmFtZXModHVtUHJvdFRhYmxlRiksIGNvbG5hbWVzKG5vcm1Qcm90VGFibGVGKSwgY29sbmFtZXMobG5UYWJsZUYpKSkKCmltZ19wcm90X2FmIDwtIGRhdGEuZnJhbWUodChkYXRhLmZyYW1lKHJiaW5kKGltZ0ZlYXRUYWJsZUZbLCBjb2xfbmFtZXNdLCB0dW1Qcm90VGFibGVGWywgY29sX25hbWVzXSwgbm9ybVByb3RUYWJsZUZbLCBjb2xfbmFtZXNdLCBsbkFmVGFibGVGWywgY29sX25hbWVzXSkpKSkKaW1nX3R1bV9hZiA8LSBkYXRhLmZyYW1lKHQoZGF0YS5mcmFtZShyYmluZChpbWdGZWF0VGFibGVGWywgY29sX25hbWVzXSwgdHVtUHJvdFRhYmxlRlssIGNvbF9uYW1lc10sIGxuQWZUYWJsZUZbLCBjb2xfbmFtZXNdKSkpKQppbWdfbm9ybV9hZiA8LSBkYXRhLmZyYW1lKHQoZGF0YS5mcmFtZShyYmluZChpbWdGZWF0VGFibGVGWywgY29sX25hbWVzXSwgbm9ybVByb3RUYWJsZUZbLCBjb2xfbmFtZXNdLCBsbkFmVGFibGVGWywgY29sX25hbWVzXSkpKSkKaW1nX2FmIDwtIGRhdGEuZnJhbWUodChkYXRhLmZyYW1lKHJiaW5kKGltZ0ZlYXRUYWJsZUZbLCBjb2xfbmFtZXNdLCBsbkFmVGFibGVGWywgY29sX25hbWVzXSkpKSkKcHJvdF9hZiA8LSBkYXRhLmZyYW1lKHQoZGF0YS5mcmFtZShyYmluZCh0dW1Qcm90VGFibGVGWywgY29sX25hbWVzXSwgbm9ybVByb3RUYWJsZUZbLCBjb2xfbmFtZXNdLCBsbkFmVGFibGVGWywgY29sX25hbWVzXSkpKSkKCmltZ19wcm90X25vIDwtIGRhdGEuZnJhbWUodChkYXRhLmZyYW1lKHJiaW5kKGltZ0ZlYXRUYWJsZUZbLCBjb2xfbmFtZXNdLCB0dW1Qcm90VGFibGVGWywgY29sX25hbWVzXSwgbm9ybVByb3RUYWJsZUZbLCBjb2xfbmFtZXNdLCBsbk5vVGFibGVGWywgY29sX25hbWVzXSkpKSkKaW1nX25vIDwtIGRhdGEuZnJhbWUodChkYXRhLmZyYW1lKHJiaW5kKGltZ0ZlYXRUYWJsZUZbLCBjb2xfbmFtZXNdLCBsbk5vVGFibGVGWywgY29sX25hbWVzXSkpKSkKcHJvdF9ubyA8LSBkYXRhLmZyYW1lKHQoZGF0YS5mcmFtZShyYmluZCh0dW1Qcm90VGFibGVGWywgY29sX25hbWVzXSwgbm9ybVByb3RUYWJsZUZbLCBjb2xfbmFtZXNdLCBsbk5vVGFibGVGWywgY29sX25hbWVzXSkpKSkKYGBgCgpgYGB7cn0KYm5faW1nX2FmIDwtIGVtcHR5LmdyYXBoKGMocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIHJvd25hbWVzKGxuQWZUYWJsZUYpKSkKd2xfaW1nX2FmIDwtIHRpZXJzMmJsYWNrbGlzdChsaXN0KHJvd25hbWVzKGxuQWZUYWJsZUYpLCByb3duYW1lcyhpbWdGZWF0VGFibGVGKSkpCmFyY3MoYm5faW1nX2FmKSA8LSB3bF9pbWdfYWYKCmJuX3Byb3RfYWYgPC0gZW1wdHkuZ3JhcGgoYyhyb3duYW1lcyh0dW1Qcm90VGFibGVGKSwgcm93bmFtZXMobm9ybVByb3RUYWJsZUYpLCByb3duYW1lcyhsbkFmVGFibGVGKSkpCndsX3Byb3RfYWYgPC0gdGllcnMyYmxhY2tsaXN0KGxpc3Qocm93bmFtZXMobG5BZlRhYmxlRiksIGMocm93bmFtZXModHVtUHJvdFRhYmxlRiksIHJvd25hbWVzKG5vcm1Qcm90VGFibGVGKSkpKQphcmNzKGJuX3Byb3RfYWYpIDwtIHdsX3Byb3RfYWYKCmJuX3Byb3RfaW1nX2FmIDwtIGVtcHR5LmdyYXBoKGMocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIHJvd25hbWVzKHR1bVByb3RUYWJsZUYpLCByb3duYW1lcyhub3JtUHJvdFRhYmxlRiksIHJvd25hbWVzKGxuQWZUYWJsZUYpKSkKd2xfcHJvdF9pbWdfYWYgPC0gcmJpbmQoCiAgdGllcnMyYmxhY2tsaXN0KGxpc3Qocm93bmFtZXMobG5BZlRhYmxlRiksIHJvd25hbWVzKGltZ0ZlYXRUYWJsZUYpKSksCiAgdGllcnMyYmxhY2tsaXN0KGxpc3Qocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIGMocm93bmFtZXModHVtUHJvdFRhYmxlRiksIHJvd25hbWVzKG5vcm1Qcm90VGFibGVGKSkpKQopCmFyY3MoYm5fcHJvdF9pbWdfYWYpIDwtIHdsX3Byb3RfaW1nX2FmCgpibl90dW1faW1nX2FmIDwtIGVtcHR5LmdyYXBoKGMocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIHJvd25hbWVzKHR1bVByb3RUYWJsZUYpLCByb3duYW1lcyhsbkFmVGFibGVGKSkpCndsX3R1bV9pbWdfYWYgPC0gcmJpbmQoCiAgdGllcnMyYmxhY2tsaXN0KGxpc3Qocm93bmFtZXMobG5BZlRhYmxlRiksIHJvd25hbWVzKGltZ0ZlYXRUYWJsZUYpKSksCiAgdGllcnMyYmxhY2tsaXN0KGxpc3Qocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIGMocm93bmFtZXModHVtUHJvdFRhYmxlRikpKSkKKQphcmNzKGJuX3R1bV9pbWdfYWYpIDwtIHdsX3R1bV9pbWdfYWYKCmJuX25vcm1faW1nX2FmIDwtIGVtcHR5LmdyYXBoKGMocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIHJvd25hbWVzKG5vcm1Qcm90VGFibGVGKSwgcm93bmFtZXMobG5BZlRhYmxlRikpKQp3bF9ub3JtX2ltZ19hZiA8LSByYmluZCgKICB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhsbkFmVGFibGVGKSwgcm93bmFtZXMoaW1nRmVhdFRhYmxlRikpKSwKICB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhpbWdGZWF0VGFibGVGKSwgcm93bmFtZXMobm9ybVByb3RUYWJsZUYpKSkKKQphcmNzKGJuX25vcm1faW1nX2FmKSA8LSB3bF9ub3JtX2ltZ19hZgoKYm5fcHJvdF9pbWdfaWRfYWYgPC0gZW1wdHkuZ3JhcGgoYyhyb3duYW1lcyhpbWdGZWF0VGFibGVGKSwgcm93bmFtZXModHVtUHJvdFRhYmxlRiksIHJvd25hbWVzKG5vcm1Qcm90VGFibGVGKSwgcm93bmFtZXMobG5BZlRhYmxlRikpKQp3bF9wcm90X2ltZ19pZF9hZiA8LSB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhsbkFmVGFibGVGKSwgYyhyb3duYW1lcyhpbWdGZWF0VGFibGVGKSwgcm93bmFtZXModHVtUHJvdFRhYmxlRiksIHJvd25hbWVzKG5vcm1Qcm90VGFibGVGKSkpKQphcmNzKGJuX3Byb3RfaW1nX2lkX2FmKSA8LSB3bF9wcm90X2ltZ19pZF9hZgpgYGAKCmBgYHtyfQpibl9pbWdfbm8gPC0gZW1wdHkuZ3JhcGgoYyhyb3duYW1lcyhpbWdGZWF0VGFibGVGKSwgcm93bmFtZXMobG5Ob1RhYmxlRikpKQp3bF9pbWdfbm8gPC0gdGllcnMyYmxhY2tsaXN0KGxpc3Qocm93bmFtZXMobG5Ob1RhYmxlRiksIHJvd25hbWVzKGltZ0ZlYXRUYWJsZUYpKSkKYXJjcyhibl9pbWdfbm8pIDwtIHdsX2ltZ19ubwoKYm5fcHJvdF9ubyA8LSBlbXB0eS5ncmFwaChjKHJvd25hbWVzKHR1bVByb3RUYWJsZUYpLCByb3duYW1lcyhub3JtUHJvdFRhYmxlRiksIHJvd25hbWVzKGxuTm9UYWJsZUYpKSkKd2xfcHJvdF9ubyA8LSB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhsbk5vVGFibGVGKSwgYyhyb3duYW1lcyh0dW1Qcm90VGFibGVGKSwgcm93bmFtZXMobm9ybVByb3RUYWJsZUYpKSkpCmFyY3MoYm5fcHJvdF9ubykgPC0gd2xfcHJvdF9ubwoKYm5fcHJvdF9pbWdfbm8gPC0gZW1wdHkuZ3JhcGgoYyhyb3duYW1lcyhpbWdGZWF0VGFibGVGKSwgcm93bmFtZXModHVtUHJvdFRhYmxlRiksIHJvd25hbWVzKG5vcm1Qcm90VGFibGVGKSwgcm93bmFtZXMobG5Ob1RhYmxlRikpKQp3bF9wcm90X2ltZ19ubyA8LSByYmluZCgKICB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhsbk5vVGFibGVGKSwgcm93bmFtZXMoaW1nRmVhdFRhYmxlRikpKSwKICB0aWVyczJibGFja2xpc3QobGlzdChyb3duYW1lcyhpbWdGZWF0VGFibGVGKSwgYyhyb3duYW1lcyh0dW1Qcm90VGFibGVGKSwgcm93bmFtZXMobm9ybVByb3RUYWJsZUYpKSkpCikKYXJjcyhibl9wcm90X2ltZ19ubykgPC0gd2xfcHJvdF9pbWdfbm8KCmJuX3Byb3RfaW1nX2lkX25vIDwtIGVtcHR5LmdyYXBoKGMocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIHJvd25hbWVzKHR1bVByb3RUYWJsZUYpLCByb3duYW1lcyhub3JtUHJvdFRhYmxlRiksIHJvd25hbWVzKGxuTm9UYWJsZUYpKSkKd2xfcHJvdF9pbWdfaWRfbm8gPC0gdGllcnMyYmxhY2tsaXN0KGxpc3Qocm93bmFtZXMobG5Ob1RhYmxlRiksIGMocm93bmFtZXMoaW1nRmVhdFRhYmxlRiksIHJvd25hbWVzKHR1bVByb3RUYWJsZUYpLCByb3duYW1lcyhub3JtUHJvdFRhYmxlRikpKSkKYXJjcyhibl9wcm90X2ltZ19pZF9ubykgPC0gd2xfcHJvdF9pbWdfaWRfbm8KYGBgCgoKYGBge3J9CmdyYXBodml6LnBsb3QoYm5faW1nX2FmKQpncmFwaHZpei5wbG90KGJuX3Byb3RfYWYpCmdyYXBodml6LnBsb3QoYm5fcHJvdF9pbWdfYWYpCmdyYXBodml6LnBsb3QoYm5fcHJvdF9pbWdfaWRfYWYpCmdyYXBodml6LnBsb3QoYm5fdHVtX2ltZ19hZikKZ3JhcGh2aXoucGxvdChibl9ub3JtX2ltZ19hZikKYGBgCgoKCmBgYHtyfQppbWdfYWZfY3YgPC0gYm4uY3YoaW1nX2FmLCBibiA9IGJuX2ltZ19hZiwgcnVucyA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCnByb3RfYWZfY3YgPC0gYm4uY3YocHJvdF9hZiwgYm4gPSBibl9wcm90X2FmLCBydW5zID0gMTAsIGxvc3MgPSAibXNlLWx3IiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiYWZmZWN0ZWQiKSkKaW1nX3Byb3RfYWZfY3YgPC0gYm4uY3YoaW1nX3Byb3RfYWYsIGJuID0gYm5fcHJvdF9pbWdfYWYsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UtbHciLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJhZmZlY3RlZCIpKQppbWdfdHVtX2FmX2N2IDwtIGJuLmN2KGltZ190dW1fYWYsIGJuID0gYm5fdHVtX2ltZ19hZiwgcnVucyA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCmltZ19ub3JtX2FmX2N2IDwtIGJuLmN2KGltZ19ub3JtX2FmLCBibiA9IGJuX25vcm1faW1nX2FmLCBydW5zID0gMTAsIGxvc3MgPSAibXNlLWx3IiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiYWZmZWN0ZWQiKSkKaW1nX3Byb3RfaWRfYWZfY3YgPC0gYm4uY3YoaW1nX3Byb3RfYWYsIGJuID0gYm5fcHJvdF9pbWdfaWRfYWYsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UtbHciLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJhZmZlY3RlZCIpKQpgYGAKCmBgYHtyfQpwbG90KGltZ19hZl9jdiwgcHJvdF9hZl9jdiwgaW1nX3Byb3RfYWZfY3YsIGltZ190dW1fYWZfY3YsIGltZ19ub3JtX2FmX2N2LCBpbWdfcHJvdF9pZF9hZl9jdiwgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyBvbmx5IiwgIlByb3Rlb21pY3MgLT4gSW1hZ2UiLCAiVHVtIHByb3QgLT4gSW1hZ2UiLCAiTm9ybSBwcm90IC0+IEltYWdlIiwgIkltYWdlICsgUHJvdGVvbWljcyIpKQpwbG90KGltZ19hZl9jdiwgaW1nX3Byb3RfYWZfY3YsIHhsYWIgPSBjKCJJbWFnZSBvbmx5IiwgIlByb3Rlb21pY3MgLT4gSW1hZ2UiKSkKcGxvdChpbWdfYWZfY3YsIGltZ19wcm90X2FmX2N2LCBpbWdfdHVtX2FmX2N2LCBpbWdfbm9ybV9hZl9jdiwgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyAtPiBJbWFnZSIsICJUdW0gcHJvdCAtPiBJbWFnZSIsICJOb3JtIHByb3QgLT4gSW1hZ2UiKSkKYGBgCgoKYGBge3J9CnNhdmUoaW1nX2FmX2N2LCBwcm90X2FmX2N2LCBpbWdfcHJvdF9hZl9jdiwgaW1nX3R1bV9hZl9jdiwgaW1nX25vcm1fYWZfY3YsIGltZ19wcm90X2lkX2FmX2N2LCBmaWxlID0gIi4vYW5hbHlzaXNfU0YvY29tcGFyaXNvbnMuUkRhdGEiKQpgYGAKCgp2YWxpZCBsZWFybmluZyBhbGdvcml0aG0ocykgYXJlICJncyIgKEdyb3ctU2hyaW5rKSwgImlhbWIiIChJQU1CKSwgImZhc3QuaWFtYiIgKEZhc3QtSUFNQiksICJpbnRlci5pYW1iIiAoSW50ZXItSUFNQiksICJpYW1iLmZkciIgKElBTUItRkRSKSwgInBjLnN0YWJsZSIgKFBDIChTdGFibGUpKSwgIm1tcGMiIChNYXgtTWluIFBhcmVudCBDaGlsZHJlbiksICJzaS5oaXRvbi5wYyIgKFNlbWktSW50ZXJsZWF2ZWQgSElUT04tUEMpLCAiaHBjIiAoSHlicmlkIFBhcmVudHMgYW5kIENoaWxkcmVuKSwgImhjIiAoSGlsbC1DbGltYmluZyksICJ0YWJ1IiAoVGFidSBTZWFyY2gpLCAicnNtYXgyIiAoVHdvLVBoYXNlIFJlc3RyaWN0ZWQgTWF4aW1pemF0aW9uKSwgIm1taGMiIChNYXgtTWluIEhpbGwtQ2xpbWJpbmcpLCAiaDJwYyIgKEh5YnJpZF4yIFBhcmVudCBDaGlsZHJlbiksICJjaG93LmxpdSIgKENob3ctTGl1KSwgImFyYWNuZSIgKEFSQUNORSksICJuYWl2ZS5iYXllcyIgKE5haXZlIEJheWVzIENsYXNzaWZpZXIpLCAidHJlZS5iYXllcyIgKFRBTiBCYXllcyBDbGFzc2lmaWVyKS4gU2VlID9ibmxlYXJuLXBhY2thZ2UgZm9yIGRldGFpbHMuCgoKYGBge3J9CmltZ19hZl9obyA8LSBibi5jdihpbWdfYWYsIGJuID0gYm5faW1nX2FmLCBydW5zID0gMTAsIG1ldGhvZCA9ICJob2xkLW91dCIsIGsgPSAxMCwgbSA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCnByb3RfYWZfaG8gPC0gYm4uY3YocHJvdF9hZiwgYm4gPSBibl9wcm90X2FmLCBydW5zID0gMTAsIG1ldGhvZCA9ICJob2xkLW91dCIsIGsgPSAxMCwgbSA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCmltZ19wcm90X2FmX2hvIDwtIGJuLmN2KGltZ19wcm90X2FmLCBibiA9IGJuX3Byb3RfaW1nX2FmLCBydW5zID0gMTAsIG1ldGhvZCA9ICJob2xkLW91dCIsIGsgPSAxMCwgbSA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCmltZ190dW1fYWZfaG8gPC0gYm4uY3YoaW1nX3R1bV9hZiwgYm4gPSBibl90dW1faW1nX2FmLCBydW5zID0gMTAsIG1ldGhvZCA9ICJob2xkLW91dCIsIGsgPSAxMCwgbSA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCmltZ19ub3JtX2FmX2hvIDwtIGJuLmN2KGltZ19ub3JtX2FmLCBibiA9IGJuX25vcm1faW1nX2FmLCBydW5zID0gMTAsIG1ldGhvZCA9ICJob2xkLW91dCIsIGsgPSAxMCwgbSA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCmltZ19wcm90X2lkX2FmX2hvIDwtIGJuLmN2KGltZ19wcm90X2FmLCBibiA9IGJuX3Byb3RfaW1nX2lkX2FmLCBydW5zID0gMTAsIG1ldGhvZCA9ICJob2xkLW91dCIsIGsgPSAxMCwgbSA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCnBsb3QoaW1nX2FmX2hvLCBwcm90X2FmX2hvLCBpbWdfcHJvdF9hZl9obywgaW1nX3R1bV9hZl9obywgaW1nX25vcm1fYWZfaG8sIGltZ19wcm90X2lkX2FmX2hvLCB4bGFiID0gYygiSW1hZ2Ugb25seSIsICJQcm90ZW9taWNzIG9ubHkiLCAiUHJvdGVvbWljcyAtPiBJbWFnZSIsICJUdW0gcHJvdCAtPiBJbWFnZSIsICJOb3JtIHByb3QgLT4gSW1hZ2UiLCAiSW1hZ2UgKyBQcm90ZW9taWNzIikpCnBsb3QoaW1nX2FmX2hvLCBpbWdfcHJvdF9hZl9obywgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyAtPiBJbWFnZSIpKQpwbG90KGltZ19hZl9obywgaW1nX3Byb3RfYWZfaG8sIGltZ190dW1fYWZfaG8sIGltZ19ub3JtX2FmX2hvLCB4bGFiID0gYygiSW1hZ2Ugb25seSIsICJQcm90ZW9taWNzIC0+IEltYWdlIiwgIlR1bSBwcm90IC0+IEltYWdlIiwgIk5vcm0gcHJvdCAtPiBJbWFnZSIpKQpgYGAKCgoKYGBge3J9CmltZ19hZl9jdiA8LSBibi5jdihpbWdfYWYsIGJuID0gYm5faW1nX2FmLCBydW5zID0gMTAsIGxvc3MgPSAibXNlLWx3IiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiYWZmZWN0ZWQiKSkKcHJvdF9hZl9jdiA8LSBibi5jdihwcm90X2FmLCBibiA9IGJuX3Byb3RfYWYsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UtbHciLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJhZmZlY3RlZCIpKQppbWdfcHJvdF9hZl9jdiA8LSBibi5jdihpbWdfcHJvdF9hZiwgYm4gPSBibl9wcm90X2ltZ19hZiwgcnVucyA9IDEwLCBsb3NzID0gIm1zZS1sdyIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCmltZ19wcm90X2lkX2FmX2N2IDwtIGJuLmN2KGltZ19wcm90X2FmLCBibiA9IGJuX3Byb3RfaW1nX2lkX2FmLCBydW5zID0gMTAsIGxvc3MgPSAibXNlLWx3IiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiYWZmZWN0ZWQiKSkKcGxvdChpbWdfYWZfY3YsIHByb3RfYWZfY3YsIGltZ19wcm90X2FmX2N2LCBpbWdfcHJvdF9pZF9hZl9jdiwgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyBvbmx5IiwgIlByb3Rlb21pY3MgLT4gSW1hZ2UiLCAiSW1hZ2UgKyBQcm90ZW9taWNzIikpCnBsb3QoaW1nX2FmX2N2LCBpbWdfcHJvdF9hZl9jdiwgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyAtPiBJbWFnZSIpKQpgYGAKCgpgYGB7cn0KaW1nX2FmX2N2IDwtIGJuLmN2KGltZ19hZiwgYm4gPSBibl9pbWdfYWYsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UiLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJhZmZlY3RlZCIpKQpwcm90X2FmX2N2IDwtIGJuLmN2KHByb3RfYWYsIGJuID0gYm5fcHJvdF9hZiwgcnVucyA9IDEwLCBsb3NzID0gIm1zZSIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gImFmZmVjdGVkIikpCmltZ19wcm90X2FmX2N2IDwtIGJuLmN2KGltZ19wcm90X2FmLCBibiA9IGJuX3Byb3RfaW1nX2FmLCBydW5zID0gMTAsIGxvc3MgPSAibXNlIiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiYWZmZWN0ZWQiKSkKaW1nX3Byb3RfaWRfYWZfY3YgPC0gYm4uY3YoaW1nX3Byb3RfYWYsIGJuID0gYm5fcHJvdF9pbWdfaWRfYWYsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UiLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJhZmZlY3RlZCIpKQpwbG90KGltZ19hZl9jdiwgcHJvdF9hZl9jdiwgaW1nX3Byb3RfYWZfY3YsIGltZ19wcm90X2lkX2FmX2N2LCB4bGFiID0gYygiSW1hZ2Ugb25seSIsICJQcm90ZW9taWNzIG9ubHkiLCAiUHJvdGVvbWljcyAtPiBJbWFnZSIsICJJbWFnZSArIFByb3Rlb21pY3MiKSkKcGxvdChpbWdfYWZfY3YsIGltZ19wcm90X2FmX2N2LCB4bGFiID0gYygiSW1hZ2Ugb25seSIsICJQcm90ZW9taWNzIC0+IEltYWdlIikpCmBgYAoKCmBgYHtyfQppbWdfbm9fY3YgPC0gYm4uY3YoaW1nX25vLCBibiA9IGJuX2ltZ19ubywgcnVucyA9IDEwLCBsb3NzID0gIm1zZSIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gIk5vTE4iKSkKcHJvdF9ub19jdiA8LSBibi5jdihwcm90X25vLCBibiA9IGJuX3Byb3Rfbm8sIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UiLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJOb0xOIikpCmltZ19wcm90X25vX2N2IDwtIGJuLmN2KGltZ19wcm90X25vLCBibiA9IGJuX3Byb3RfaW1nX25vLCBydW5zID0gMTAsIGxvc3MgPSAibXNlIiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiTm9MTiIpKQppbWdfcHJvdF9pZF9ub19jdiA8LSBibi5jdihpbWdfcHJvdF9ubywgYm4gPSBibl9wcm90X2ltZ19pZF9ubywgcnVucyA9IDEwLCBsb3NzID0gIm1zZSIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gIk5vTE4iKSkKcGxvdChpbWdfbm9fY3YsIHByb3Rfbm9fY3YsIGltZ19wcm90X25vX2N2LCBpbWdfcHJvdF9pZF9ub19jdiwgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyBvbmx5IiwgIlByb3Rlb21pY3MgLT4gSW1hZ2UiLCAiSW1hZ2UgKyBQcm90ZW9taWNzIikpCnBsb3QoaW1nX25vX2N2LCBpbWdfcHJvdF9ub19jdiwgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyAtPiBJbWFnZSIpKQpgYGAKCgoKCgoKCgojIFRlc3RzCgpgYGB7cn0KaW1nX2FmX2N2IDwtIGJuLmN2KGltZ19hZiwgYm4gPSAiaGMiLCBydW5zID0gMTAsIGxvc3MgPSAibXNlIiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiYWZmZWN0ZWQiKSkKcHJvdF9hZl9jdiA8LSBibi5jdihwcm90X2FmLCBibiA9ICJoYyIsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UiLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJhZmZlY3RlZCIpKQppbWdfcHJvdF9hZl9jdiA8LSBibi5jdihpbWdfcHJvdF9hZiwgYm4gPSAiaGMiLCBydW5zID0gMTAsIGxvc3MgPSAibXNlIiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiYWZmZWN0ZWQiKSkKcGxvdChpbWdfYWZfY3YsIHByb3RfYWZfY3YsIGltZ19wcm90X2FmX2N2LCB4bGFiID0gYygiSW1hZ2Ugb25seSIsICJQcm90ZW9taWNzIG9ubHkiLCAiSW1hZ2UgKyBQcm90ZW9taWNzIikpCmBgYAoKCmBgYHtyfQppbWdfbm9fY3YgPC0gYm4uY3YoaW1nX25vLCBibiA9ICJ0YWJ1IiwgcnVucyA9IDEwLCBsb3NzID0gIm1zZSIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gIk5vTE4iKSkKcHJvdF9ub19jdiA8LSBibi5jdihwcm90X25vLCBibiA9ICJ0YWJ1IiwgcnVucyA9IDEwLCBsb3NzID0gIm1zZSIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gIk5vTE4iKSkKaW1nX3Byb3Rfbm9fY3YgPC0gYm4uY3YoaW1nX3Byb3Rfbm8sIGJuID0gInRhYnUiLCBydW5zID0gMTAsIGxvc3MgPSAibXNlIiwgbG9zcy5hcmdzID0gbGlzdCh0YXJnZXQgPSAiTm9MTiIpKQpwbG90KGltZ19ub19jdiwgcHJvdF9ub19jdiwgaW1nX3Byb3Rfbm9fY3YsIHhsYWIgPSBjKCJJbWFnZSBvbmx5IiwgIlByb3Rlb21pY3Mgb25seSIsICJJbWFnZSArIFByb3Rlb21pY3MiKSkKYGBgCgoKYGBge3J9CmltZ19ub19jdiA8LSBibi5jdihpbWdfbm8sIGJuID0gImhjIiwgcnVucyA9IDEwLCBsb3NzID0gIm1zZSIsIGxvc3MuYXJncyA9IGxpc3QodGFyZ2V0ID0gIk5vTE4iKSkKcHJvdF9ub19jdiA8LSBibi5jdihwcm90X25vLCBibiA9ICJoYyIsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UiLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJOb0xOIikpCmltZ19wcm90X25vX2N2IDwtIGJuLmN2KGltZ19wcm90X25vLCBibiA9ICJoYyIsIHJ1bnMgPSAxMCwgbG9zcyA9ICJtc2UiLCBsb3NzLmFyZ3MgPSBsaXN0KHRhcmdldCA9ICJOb0xOIikpCnBsb3QoaW1nX25vX2N2LCBwcm90X25vX2N2LCBpbWdfcHJvdF9ub19jdiwgeGxhYiA9IGMoIkltYWdlIG9ubHkiLCAiUHJvdGVvbWljcyBvbmx5IiwgIkltYWdlICsgUHJvdGVvbWljcyIpKQpgYGAKCgojIFVzaW5nIG90aGVyIG1vZGVscyB0byBkbyB0aGUgY3Jvc3MgdmFsaWRhdGlvbiwgbGlrZSBBdXRvTUw/CgpgYGB7cn0KCmBgYAoKCgojIEhpZGRlbiBNYXJrb3YgTW9kZWwgZm9yIG1vZGVsaW5nIHRoZSBseW1waGlub2RlIGR5bmFtaWNzCgoKCgoKCgoKCgoKCgoK